# allow build systems to use a constant date instead of the current one
CFG_BUILD_DATE = $(shell SOURCE_DATE_EPOCH="$${SOURCE_DATE_EPOCH:-$$(date +%s)}" ; date -u -d "@$$SOURCE_DATE_EPOCH" +%F 2>/dev/null || date -u -r "$$SOURCE_DATE_EPOCH" +%F 2>/dev/null || date -u +%F)
-ifeq ($(wildcard $(CFG_SRC_DIR)/.git),)
-CFG_VERSION = $(CFG_RELEASE) (built $(CFG_BUILD_DATE))
-else
-CFG_VER_DATE = $(shell git --git-dir='$(CFG_SRC_DIR).git' log -1 --date=short --pretty=format:'%cd')
-CFG_VER_HASH = $(shell git --git-dir='$(CFG_SRC_DIR).git' rev-parse --short HEAD)
-CFG_VERSION = $(CFG_RELEASE) ($(CFG_VER_HASH) $(CFG_VER_DATE))
+ifneq ($(wildcard $(CFG_SRC_DIR)/.git),)
+CFG_COMMIT_DATE = $(shell git --git-dir='$(CFG_SRC_DIR).git' log -1 --date=short --pretty=format:'%cd')
+CFG_SHORT_COMMIT_HASH = $(shell git --git-dir='$(CFG_SRC_DIR).git' rev-parse --short HEAD)
+CFG_COMMIT_HASH = $(shell git --git-dir='$(CFG_SRC_DIR).git' rev-parse HEAD)
endif
PKG_NAME = cargo-$(CFG_PACKAGE_VERS)
S := $(CFG_SRC_DIR)/
+CFG_RELEASE_PARTS := $(subst ., ,$(CFG_RELEASE_NUM))
+CFG_VERSION_MAJOR := $(word 1,$(CFG_RELEASE_PARTS))
+CFG_VERSION_MINOR := $(word 2,$(CFG_RELEASE_PARTS))
+CFG_VERSION_PATCH := $(word 3,$(CFG_RELEASE_PARTS))
+
export CFG_VERSION
+export CFG_VERSION_MAJOR
+export CFG_VERSION_MINOR
+export CFG_VERSION_PATCH
+ifneq ($(CFG_PRERELEASE_VERSION),)
+export CFG_PRERELEASE_VERSION
+endif
+ifneq ($(CFG_COMMIT_HASH),)
+export CFG_COMMIT_HASH
+export CFG_COMMIT_DATE
+export CFG_SHORT_COMMIT_HASH
+endif
+export CFG_BUILD_DATE
+export CFG_RELEASE_CHANNEL
export CFG_DISABLE_CROSS_TESTS
ifeq ($(OS),Windows_NT)
extern crate url;
use std::env;
+use std::fmt;
use std::io;
use rustc_serialize::{Decodable, Encodable};
use rustc_serialize::json;
pub mod sources;
pub mod util;
+pub struct CommitInfo {
+ pub short_commit_hash: String,
+ pub commit_hash: String,
+ pub commit_date: String,
+}
+
+pub struct CfgInfo {
+ // Information about the git repository we may have been built from.
+ pub commit_info: Option<CommitInfo>,
+ // The date that the build was performed.
+ pub build_date: String,
+ // The release channel we were built for.
+ pub release_channel: String,
+}
+
+pub struct VersionInfo {
+ pub major: String,
+ pub minor: String,
+ pub patch: String,
+ pub pre_release: Option<String>,
+ // Information that's only available when we were built with
+ // configure/make, rather than cargo itself.
+ pub cfg_info: Option<CfgInfo>,
+}
+
+impl fmt::Display for VersionInfo {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "cargo-{}.{}.{}",
+ self.major, self.minor, self.patch)?;
+ match self.cfg_info.as_ref().map(|ci| &ci.release_channel) {
+ Some(channel) => {
+ if channel != "stable" {
+ write!(f, "-{}", channel)?;
+ let empty = String::from("");
+ write!(f, "{}", self.pre_release.as_ref().unwrap_or(&empty))?;
+ }
+ },
+ None => (),
+ };
+
+ if let Some(ref cfg) = self.cfg_info {
+ match cfg.commit_info {
+ Some(ref ci) => {
+ write!(f, " ({} {})",
+ ci.short_commit_hash, ci.commit_date)?;
+ },
+ None => {
+ write!(f, " (built {})",
+ cfg.build_date)?;
+ }
+ }
+ };
+ Ok(())
+ }
+}
+
pub fn execute_main_without_stdin<T, V>(
exec: fn(T, &Config) -> CliResult<Option<V>>,
options_first: bool,
}
}
-pub fn version() -> String {
- format!("cargo {}", match option_env!("CFG_VERSION") {
- Some(s) => s.to_string(),
- None => format!("{}.{}.{}{}",
- env!("CARGO_PKG_VERSION_MAJOR"),
- env!("CARGO_PKG_VERSION_MINOR"),
- env!("CARGO_PKG_VERSION_PATCH"),
- option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
- })
+pub fn version() -> VersionInfo {
+ macro_rules! env_str {
+ ($name:expr) => { env!($name).to_string() }
+ }
+ macro_rules! option_env_str {
+ ($name:expr) => { option_env!($name).map(|s| s.to_string()) }
+ }
+ match option_env!("CFG_RELEASE_CHANNEL") {
+ // We have environment variables set up from configure/make.
+ Some(_) => {
+ let commit_info =
+ option_env!("CFG_COMMIT_HASH").map(|s| {
+ CommitInfo {
+ commit_hash: s.to_string(),
+ short_commit_hash: option_env_str!("CFG_SHORT_COMMIT_HASH").unwrap(),
+ commit_date: option_env_str!("CFG_COMMIT_DATE").unwrap(),
+ }
+ });
+ VersionInfo {
+ major: option_env_str!("CFG_VERSION_MAJOR").unwrap(),
+ minor: option_env_str!("CFG_VERSION_MINOR").unwrap(),
+ patch: option_env_str!("CFG_VERSION_PATCH").unwrap(),
+ pre_release: option_env_str!("CFG_PRERELEASE_VERSION"),
+ cfg_info: Some(CfgInfo {
+ build_date: option_env_str!("CFG_BUILD_DATE").unwrap(),
+ release_channel: option_env_str!("CFG_RELEASE_CHANNEL").unwrap(),
+ commit_info: commit_info,
+ }),
+ }
+ },
+ // We are being compiled by Cargo itself.
+ None => {
+ VersionInfo {
+ major: env_str!("CARGO_PKG_VERSION_MAJOR"),
+ minor: env_str!("CARGO_PKG_VERSION_MINOR"),
+ patch: env_str!("CARGO_PKG_VERSION_PATCH"),
+ pre_release: option_env_str!("CARGO_PKG_VERSION_PRE"),
+ cfg_info: None,
+ }
+ }
+ }
}
fn flags_from_args<T>(usage: &str, args: &[String], options_first: bool) -> CliResult<T>